#pragma once

#include <atomic>
#include <cassert>
#include <cstdio>
#include <stdlib.h>
#include <string>
#include <type_traits>

/**
 * Preprocessors
 */
#if __cplusplus >= 201103L
#define _TX_FINAL final
#define _TX_OVERRIDE override
#define _TX_NOEXCEPT noexcept
#else
#define _TX_FINAL
#define _TX_OVERRIDE
#define _TX_NOEXCEPT
#endif // __cplusplus >= 201103L

// 控制符号(函数或变量)在编译后二进制文件中的可见性
// 符号的可见性决定了它们是否可以被其他模块访问
// __attribute__((visibility("default")))：默认可见性，可以被其他模块访问
// __attribute__((visibility("hidden")))：隐藏可见性，只能在定义它们的模块中访问
// 确保函数或变量在动态链接库中对外可见, 对API发布和调用非常重要
#ifdef TX_BUILD_LIB
#if defined(_MSC_VER)
#define TXAPI __declspec(dllexport)
#elif defined(__GNUC__)
#define TXAPI __attribute__((__visibility__("default")))
#else
#define TXAPI
#endif // _MSC_VER
#else
#define TXAPI
#endif // TX_BUILD_LIB

/**
 * Class Helper Macros
 */
#define NONCOPYABLE(Class)      \
  Class(const Class&) = delete; \
  Class& operator=(const Class&) = delete

#define NONMOVABLE(Class)  \
  Class(Class&&) = delete; \
  Class& operator=(Class&&) = delete

#define NONCOPYABLE_AND_NONMOVABLE(Class) \
  NONCOPYABLE(Class);                     \
  NONMOVABLE(Class)

#define DEFAULT_CTOR(Class) \
  Class() _TX_NOEXCEPT {}

#define CONSTEXPR_DEFAULT_CTOR(Class) \
  constexpr Class() _TX_NOEXCEPT {}

#define VIRTUAL_DEFAULT_DTOR(Class) virtual ~Class() _TX_NOEXCEPT = default

#define ROOT_INTERFACE(Class)   \
protected:                      \
  CONSTEXPR_DEFAULT_CTOR(Class) \
                                \
public:                         \
  VIRTUAL_DEFAULT_DTOR(Class);  \
  NONCOPYABLE(Class)

#define ROOT_INTERFACE_PROTECTED_DTOR(Class) \
protected:                                   \
  CONSTEXPR_DEFAULT_CTOR(Class)              \
  VIRTUAL_DEFAULT_DTOR(Class);               \
                                             \
public:                                      \
  NONCOPYABLE(Class)

#define COPY_CTOR(Class) \
  Class(const Class& rhs) _TX_NOEXCEPT { *this = rhs; }

#define MOVE_CTOR(Class) \
  Class(Class&& rhs) _TX_NOEXCEPT { *this = std::move(rhs); }

#define COPY_AND_MOVE_CTORS(Class) \
  COPY_CTOR(Class)                 \
  MOVE_CTOR(Class)

/**
 * Message Common Helper
 */
/**
 * @brief 生成错误消息的宏。
 *
 * 此宏用于生成包含文件名、行号和函数名的错误消息，方便定位错误位置。
 *
 * @param msg 错误描述信息。
 */
#define ERROR_MSG(msg)                                                    \
  (std::string("Error in ") + __FILE__ + ":" + std::to_string(__LINE__) + \
   " (" + __FUNCTION__ + "): " + msg)

/**
 * Class Common Helper
 */
namespace common {

/**
 * NonCopyable
 */
class NonCopyable {
public:
  NonCopyable(const NonCopyable&) = delete;
  NonCopyable& operator=(const NonCopyable&) = delete;

protected:
  constexpr NonCopyable() _TX_NOEXCEPT = default;
  ~NonCopyable() _TX_NOEXCEPT = default;
};

/**
 * ILogger
 */
class ILogger {
public:
  enum class Level : int32_t {
    Emergent,
    Alert,
    Critical,
    Error,
    Warning,
    Notice,
    Info,
    Debug,
    Verbose,
    Invalid = 99,
  };

public:
  ROOT_INTERFACE(ILogger);

  virtual void log(Level level, const char* msg) _TX_NOEXCEPT = 0;
  virtual bool isLogLevelEnabled(Level level) _TX_NOEXCEPT = 0;
};

/**
 * ISpinLock
 */
class ISpinLock {
public:
  ROOT_INTERFACE_PROTECTED_DTOR(ISpinLock);

  virtual void lock() _TX_NOEXCEPT = 0;
  virtual void unlock() _TX_NOEXCEPT = 0;

protected:
  std::atomic_flag lock_ = ATOMIC_FLAG_INIT;
};

} // namespace common

/*
 * TX_GetDefaultLogger Declaration
 */
extern "C" TXAPI common::ILogger* TX_GetDefaultLogger(
  const char* file_path = nullptr,
  common::ILogger::Level level = common::ILogger::Level::Error) _TX_NOEXCEPT;

/* 
 * initLogger 
 */
extern "C" TXAPI void initLogger(
  common::ILogger* logger = nullptr, std::string file_path = nullptr,
  common::ILogger::Level level = common::ILogger::Level::Debug) _TX_NOEXCEPT;